'use strict';

var utils = require('./../utils');

function InterceptorManager() {
    // 处理方法作为数组依次执行
    this.handlers = [];
}

/**
 * Add a new interceptor to the stack
 *
 * @param {Function} fulfilled The function to handle `then` for a `Promise`
 * @param {Function} rejected The function to handle `reject` for a `Promise`
 *
 * @return {Number} An ID used to remove interceptor later
 */
// 这里的精妙之处在于拦截器本质上只负责保存回调函数和配置，异步（同步）处理的部分完全交给了Axios中的处理链
InterceptorManager.prototype.use = function use(fulfilled, rejected, options) {
    this.handlers.push({
        // 成功会调
        fulfilled: fulfilled,
        // 失败回调
        rejected: rejected,
        // 是否为同步函数
        synchronous: options ? options.synchronous : false,
        runWhen: options ? options.runWhen : null
    });
    return this.handlers.length - 1;
    // 注意这里返回的是一个下标，函数利用下标值来完成对拦截器的删除或调用
};

/**
 * Remove an interceptor from the stack
 *
 * @param {Number} id The ID that was returned by `use`
通过use方法拿到id，利用id删除对应元素
 */
InterceptorManager.prototype.eject = function eject(id) {
    if (this.handlers[id]) {
        this.handlers[id] = null;
    }
};

/**
 * Iterate over all the registered interceptors
 *
 * This method is particularly useful for skipping over any
 * interceptors that may have become `null` calling `eject`.
 *
 * @param {Function} fn The function to call for each interceptor
 */
InterceptorManager.prototype.forEach = function forEach(fn) {
    utils.forEach(this.handlers, function forEachHandler(h) {
        if (h !== null) {
            // 对于数组的每一项，只要有值就调用该函数（确认还没有被销毁）
            // 这里的fn就是将所有拦截器放入执行链的push
            fn(h);
        }
    });
};

module.exports = InterceptorManager;